package org.amuthu.expression.binary;

import org.amuthu.expression.Expression;
import org.amuthu.expression.exception.TypeMismatchException;
import org.amuthu.parser.ExpressionVisitor;

/**
 * Abstract base class for the boolean expressions:
 * <code>and, or</code>
 */
public class LogicExpression extends BinaryExpression
{

   private LogicExprType exprType;

   public LogicExprType getExprType()
   {
      return exprType;
   }

   /**
    * Create a new logic expression with the given left and
    * right arguments.
    */
   public LogicExpression(LogicExprType exprType, Expression left, Expression right)
   {
      super(left, right);
      this.exprType = exprType;
   }

   /**
    * Check the input arguments to the expression. They must both be
    * {@link #BOOLEAN_TYPE}.
    *
    * @return	{@link #BOOLEAN_TYPE}
    */
   @Override
   public int checkType() throws TypeMismatchException
   {
      // both types must be boolean
      int leftType = getChild(0).checkType();
      int rightType = getChild(1).checkType();

      if (leftType == BOOLEAN_TYPE && rightType == BOOLEAN_TYPE)
      {
         return BOOLEAN_TYPE;
      }
      else
      {
         String types = getChild(0).checkType() + " , " + getChild(1).checkType();

         String expectedTypes = BOOLEAN_TYPE + " , " + BOOLEAN_TYPE;

         throw new TypeMismatchException(this, types, expectedTypes);
      }
   }

   /**
    * Get the type of the expression.
    *
    * @return {@link #BOOLEAN_TYPE}.
    */
   @Override
   public int getType()
   {
      return BOOLEAN_TYPE;
   }

   /**
    * Helper method to convert the given expression to a string.
    * Given an operator such as <code>and</code>, <code>or</code> etc
    * it will return <code>arg1 operator arg2</code>. It will insert
    * parentheses as needed.
    *
    * @param	operator	the binary operator
    * @return	the string representation
    */
   @Override
   public  String toString()
   {
      if (exprType == LogicExprType.AND)
      {
         return super.toString(" and ");
      }
      else
      {
         return super.toString(" or ");
      }
   }

   @Override
   public void accept(ExpressionVisitor visitor)
   {
      visitor.visit(this);
   }
}
